/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package callback.serveur;

import callback.client.CallbackClientInterface;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author TealeaF
 */
public class CallbackServeurImpl extends UnicastRemoteObject implements CallbackServeurInterface {

    public final String awake = new String();
    public BigDecimal pi = new BigDecimal(BigInteger.ZERO);
    private HashMap<CallbackClientInterface, String> listeClient;
    private int decimax;
    private int decimin;
    private int step;
    private int nbDecimal;
    private int nbServeur = 0;
    private int nbReponse = 0;

    public CallbackServeurImpl() throws RemoteException {
        super();
        listeClient = new HashMap<>();
        decimin = 0;
        decimax = 100;
    }

    public CallbackServeurImpl(int nbDecimal, int nbServeur) throws RemoteException {
        super();
        listeClient = new HashMap<>();
//        this.s = s;
//        decimin = Integer.parseInt(s.split(";")[0]);
        decimax = nbDecimal;

        this.nbDecimal = nbDecimal;
        this.nbServeur = nbServeur;
        decimin = decimax - nbDecimal / nbServeur;
        step = decimax - decimin;

    }

    @Override
    public void setPi(BigDecimal p) throws RemoteException {
        nbReponse++;
        pi = pi.add(p);
        if (estTermine()) {
//            synchronized (awake) {
//                awake.notify();
//            }
            notification();
        }
    }

    @Override
    public synchronized void abonnement(CallbackClientInterface objClient) throws RemoteException {
        if (!listeClient.containsKey(objClient)) {
//            listeClient.add(objClient);
            listeClient.put(objClient, decimin + ";" + decimax + ";" + nbDecimal);
            decimin -= step;
            decimax -= step;
            
            //calculdepi

            System.out.println("Abonnement d'un nouveau client");
//            nbServeur++;
//            System.out.println("Il y a maintenant " + nbServeur + " serveurs");
            executeCallbacks();
        }
    }

    @Override
    public synchronized void desabonnement(CallbackClientInterface objClient) throws RemoteException {

        if (listeClient.remove(objClient) != null) {
            System.out.println("Desabonnement du client");
        } else {
            System.out.println("Erreur: le client n'est pas enregistré");
        }
    }

    private synchronized void executeCallbacks() throws RemoteException {
//        for (int i = 0; i < listeClient.size(); i++) {
        int i = 0;
        for (CallbackClientInterface client : listeClient.keySet()) {
            System.out.println("Callback vers client " + i++);
            client.notification("message du serveur vers " + listeClient.size() + " client(s).");
        }
        System.out.println("Fin des callbacks");
    }

    @Override
    public String calculPi(CallbackClientInterface objClient) throws RemoteException {
        if (listeClient.containsKey(objClient)) {
            return listeClient.get(objClient);
        }
        return pi.toString();
    }

    @Override
    public boolean estTermine() throws RemoteException {
        System.out.println(nbReponse + "/" + nbServeur + " recus");
        return nbReponse == nbServeur;
    }
    
    @Override
    public void notification() throws RemoteException {
        System.out.println(pi.toString());
    }
}
